package com.easylive.service.impl;

import java.util.Date;
import java.util.List;
import java.util.Objects;

import javax.annotation.Resource;

import com.easylive.entity.component.RedisComponent;
import com.easylive.entity.constants.Constants;
import com.easylive.entity.dto.SysSettingDto;
import com.easylive.entity.dto.TokenUserInfoDto;
import com.easylive.entity.enums.*;
import com.easylive.entity.po.UserAction;
import com.easylive.entity.po.UserFocus;
import com.easylive.entity.po.VideoInfo;
import com.easylive.entity.query.*;
import com.easylive.exception.BusinessException;
import com.easylive.mappers.UserActionMapper;
import com.easylive.mappers.UserFocusMapper;
import com.easylive.mappers.VideoInfoMapper;
import com.easylive.utils.CopyTools;
import org.springframework.stereotype.Service;

import com.easylive.entity.po.UserInfo;
import com.easylive.entity.vo.PaginationResultVO;
import com.easylive.mappers.UserInfoMapper;
import com.easylive.service.UserInfoService;
import com.easylive.utils.StringTools;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;


/**
 * 用户信息表 业务接口实现
 */
@Service("userInfoService")
public class UserInfoServiceImpl implements UserInfoService {

	@Resource
	private UserInfoMapper<UserInfo, UserInfoQuery> userInfoMapper;

	@Resource
	private RedisComponent redisComponent;

	@Resource
	private UserFocusMapper<UserFocus, UserFocusQuery> userFocusMapper;

	@Resource
	private UserActionMapper<UserAction, UserActionQuery> userActionMapper;

	@Resource
	private VideoInfoMapper<VideoInfo, VideoInfoQuery> videoInfoMapper;

	/**
	 * 根据条件查询列表
	 */
	@Override
	public List<UserInfo> findListByParam(UserInfoQuery param) {
		return this.userInfoMapper.selectList(param);
	}

	/**
	 * 根据条件查询列表
	 */
	@Override
	public Integer findCountByParam(UserInfoQuery param) {
		return this.userInfoMapper.selectCount(param);
	}

	/**
	 * 分页查询方法
	 */
	@Override
	public PaginationResultVO<UserInfo> findListByPage(UserInfoQuery param) {
		int count = this.findCountByParam(param);
		int pageSize = param.getPageSize() == null ? PageSize.SIZE15.getSize() : param.getPageSize();

		SimplePage page = new SimplePage(param.getPageNo(), count, pageSize);
		param.setSimplePage(page);
		List<UserInfo> list = this.findListByParam(param);
		PaginationResultVO<UserInfo> result = new PaginationResultVO(count, page.getPageSize(), page.getPageNo(), page.getPageTotal(), list);
		return result;
	}

	/**
	 * 新增
	 */
	@Override
	public Integer add(UserInfo bean) {
		return this.userInfoMapper.insert(bean);
	}

	/**
	 * 批量新增
	 */
	@Override
	public Integer addBatch(List<UserInfo> listBean) {
		if (listBean == null || listBean.isEmpty()) {
			return 0;
		}
		return this.userInfoMapper.insertBatch(listBean);
	}

	/**
	 * 批量新增或者修改
	 */
	@Override
	public Integer addOrUpdateBatch(List<UserInfo> listBean) {
		if (listBean == null || listBean.isEmpty()) {
			return 0;
		}
		return this.userInfoMapper.insertOrUpdateBatch(listBean);
	}

	/**
	 * 多条件更新
	 */
	@Override
	public Integer updateByParam(UserInfo bean, UserInfoQuery param) {
		StringTools.checkParam(param);
		return this.userInfoMapper.updateByParam(bean, param);
	}

	/**
	 * 多条件删除
	 */
	@Override
	public Integer deleteByParam(UserInfoQuery param) {
		StringTools.checkParam(param);
		return this.userInfoMapper.deleteByParam(param);
	}

	/**
	 * 根据UserId获取对象
	 */
	@Override
	public UserInfo getUserInfoByUserId(String userId) {
		return this.userInfoMapper.selectByUserId(userId);
	}

	/**
	 * 根据UserId修改
	 */
	@Override
	public Integer updateUserInfoByUserId(UserInfo bean, String userId) {
		return this.userInfoMapper.updateByUserId(bean, userId);
	}

	/**
	 * 根据UserId删除
	 */
	@Override
	public Integer deleteUserInfoByUserId(String userId) {
		return this.userInfoMapper.deleteByUserId(userId);
	}

	/**
	 * 根据Email获取对象
	 */
	@Override
	public UserInfo getUserInfoByEmail(String email) {
		return this.userInfoMapper.selectByEmail(email);
	}

	/**
	 * 根据Email修改
	 */
	@Override
	public Integer updateUserInfoByEmail(UserInfo bean, String email) {
		return this.userInfoMapper.updateByEmail(bean, email);
	}

	/**
	 * 根据Email删除
	 */
	@Override
	public Integer deleteUserInfoByEmail(String email) {
		return this.userInfoMapper.deleteByEmail(email);
	}

	/**
	 * 根据NickName获取对象
	 */
	@Override
	public UserInfo getUserInfoByNickName(String nickName) {
		return this.userInfoMapper.selectByNickName(nickName);
	}

	/**
	 * 根据NickName修改
	 */
	@Override
	public Integer updateUserInfoByNickName(UserInfo bean, String nickName) {
		return this.userInfoMapper.updateByNickName(bean, nickName);
	}

	/**
	 * 根据NickName删除
	 */
	@Override
	public Integer deleteUserInfoByNickName(String nickName) {
		return this.userInfoMapper.deleteByNickName(nickName);
	}

	@Override
	public void register(String email, String registerPassword, String nickName) {

		UserInfo userInfoByEmail = userInfoMapper.selectByEmail(email);
		if (!ObjectUtils.isEmpty(userInfoByEmail)) {
			throw new BusinessException("邮箱已被注册");
		}

		UserInfo userInfoByNickName = userInfoMapper.selectByEmail(nickName);
		if (!ObjectUtils.isEmpty(userInfoByNickName)) {
			throw new BusinessException("昵称已被使用");
		}

		Date cudDate = new Date();

		UserInfo userInfo = new UserInfo();
		userInfo.setUserId(StringTools.getRandomNumber(Constants.LENGTH_10));
		userInfo.setEmail(email);
		userInfo.setPassword(StringTools.encodePassword(registerPassword));
		userInfo.setNickName(nickName);
		userInfo.setSex(UserSexEnum.UNKNOWN.getCode());
		userInfo.setJoinTime(cudDate);
		userInfo.setStatus(UserStatusEnum.NORMAL.getCode());

		// 初始硬币
		userInfo.setCurrentIconCount(Constants.INITIAL_COINS);
		userInfo.setTotalIconCount(Constants.INITIAL_COINS);
		// 主题
		userInfo.setTheme(ThemeEnum.DEFAULT.getCode());

		userInfoMapper.insert(userInfo);
	}

	@Override
	public TokenUserInfoDto login(String email, String password, String ipAddr) {
		UserInfo userInfo = userInfoMapper.selectByEmail(email);
		// 校验用户名密码
		if (ObjectUtils.isEmpty(userInfo) || !Objects.equals(password, userInfo.getPassword())) {
			throw new BusinessException("用户名或密码错误");
		}

		if (Objects.equals(userInfo.getStatus(), UserStatusEnum.DISABLED.getCode())) {
			throw new BusinessException("用户已被禁用");
		}

		// 更细登录时间，IP
		UserInfo updateUserInfo = new UserInfo();
		updateUserInfo.setLastLoginTime(new Date());
		updateUserInfo.setLastLoginIp(ipAddr);
		userInfoMapper.updateByUserId(updateUserInfo, userInfo.getUserId());

		// 返回DTO
		TokenUserInfoDto tokenUserInfoDto = CopyTools.copy(userInfo, TokenUserInfoDto.class);
		redisComponent.saveTokenInfo(tokenUserInfoDto);

		return tokenUserInfoDto;
	}

	@Override
	public UserInfo getUserDetailInfo(String currentUserId, String userId) {
		UserInfo userInfo = getUserInfoByUserId(userId);
		if (userInfo == null) {
			throw new BusinessException(ResponseCodeEnum.CODE_404);
		}
		// 获赞数 播放数
		UserActionQuery userActionQuery = new UserActionQuery();
		userActionQuery.setVideoUserId(userId);
		userActionQuery.setActionType(UserActionTypeEnum.VIDEO_LIKE.getType());
		Integer likeCount = userActionMapper.selectCount(userActionQuery);
		userInfo.setLikeCount(likeCount);

		VideoInfoQuery videoInfoQuery = new VideoInfoQuery();
		videoInfoQuery.setUserId(userId);
		videoInfoQuery.setStatus(VideoStatusEnum.STATUS3.getStatus());
		List<VideoInfo> videoInfoList = videoInfoMapper.selectList(videoInfoQuery);
		Integer playCount = 0;
		for (VideoInfo videoInfo : videoInfoList) {
			playCount = playCount + Integer.valueOf(videoInfo.getPlayCount());
		}
		userInfo.setPlayCount(playCount);

		Integer fansCount = userFocusMapper.selectFansCount(userId);
		Integer focusCount = userFocusMapper.selectFocusCount(userId);
		userInfo.setFansCount(fansCount);
		userInfo.setFocusCount(focusCount);
		if (currentUserId == null) {
			// 未登录
			userInfo.setHaveFocus(false);
		} else {
			UserFocus userFocus = userFocusMapper.selectByUserIdAndFocusUserId(currentUserId, userId);
			userInfo.setHaveFocus(userFocus == null ? false : true);
		}

		return userInfo;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateUserInfo(UserInfo userInfo, TokenUserInfoDto tokenUserInfoDto) {
		SysSettingDto sysSetting = redisComponent.getSysSetting();
		UserInfo dbUserInfo = userInfoMapper.selectByUserId(tokenUserInfoDto.getUserId());
		// 修改了昵称，需要扣硬币
		if (!dbUserInfo.getNickName().equals(userInfo.getNickName()) && dbUserInfo.getCurrentIconCount() < sysSetting.getUpdateNicknameCoinCount()) {
			throw new BusinessException("硬币不足，无法修改昵称");
		}

		// 扣硬币
		if (!dbUserInfo.getNickName().equals(userInfo.getNickName())) {
			Integer count = userInfoMapper.updateCoinCountInfo(dbUserInfo.getUserId(), -sysSetting.getUpdateNicknameCoinCount());
			if (count == 0) {
				throw new BusinessException("硬币不足，无法修改昵称");
			}
		}
		userInfoMapper.updateByUserId(userInfo, tokenUserInfoDto.getUserId());

		Boolean updateTokenFlag = false;
		if (!Objects.equals(tokenUserInfoDto.getAvatar(), userInfo.getAvatar()) ||
		    !Objects.equals(tokenUserInfoDto.getNickName(), userInfo.getNickName())) {
			updateTokenFlag = true;
		}

		if (updateTokenFlag) {
			// 更新token
			tokenUserInfoDto.setNickName(userInfo.getNickName());
			tokenUserInfoDto.setAvatar(userInfo.getAvatar());
			redisComponent.updateTokenInfo(tokenUserInfoDto);
		}
	}
}